package com.ruoyi.stock2.thread.aboutDownloadData;

import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.stock2.domain.DownTradedataFail;
import com.ruoyi.stock2.domain.DownTradedataSchedule;
import com.ruoyi.stock2.domain.STOCK;
import com.ruoyi.stock2.domain.TRADEDATA;
import com.ruoyi.stock2.mapper.DownTradedataScheduleMapper;
import com.ruoyi.stock2.mapper.STOCKMapper;
import com.ruoyi.stock2.mapper.TRADEDATAMapper;
import com.ruoyi.stock2.service.IDownTradedataFailService;
import com.ruoyi.stock2.utils.DateUtils2;
import org.jsoup.Connection.Response;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

//数据从 163网站下载
public class DownLoadStockTradeDataFromQQ2 {
    private static final Logger log = LoggerFactory.getLogger(DownLoadStockTradeDataFromQQ2.class);
    DownTradedataScheduleMapper downLoadTradedataScheduleMapper;
    STOCKMapper stockMapper;
    TRADEDATAMapper tradedataMapper;
    UpdateStocksSymbolDataService updateStocksSymbolDataService;
    IDownTradedataFailService iDownTradedataFailService;
    String now163Date = null;

    public String getNow163Date() {
        return now163Date;
    }

    public void setNow163Date(String now163Date) {
        this.now163Date = now163Date;
    }

    //单例实现 涉及到任务状态
    public static DownLoadStockTradeDataFromQQ2 getInstance() {
        return Singtonle.instance;
    }

    private static class Singtonle {
        private static DownLoadStockTradeDataFromQQ2 instance = new DownLoadStockTradeDataFromQQ2();
    }


    boolean whileflag11 = true;

    public void run() {
        //初始化实例
        downLoadTradedataScheduleMapper = (DownTradedataScheduleMapper) SpringUtils.getBean(DownTradedataScheduleMapper.class);
        tradedataMapper = (TRADEDATAMapper) SpringUtils.getBean(TRADEDATAMapper.class);
        stockMapper = (STOCKMapper) SpringUtils.getBean(STOCKMapper.class);
        updateStocksSymbolDataService = (UpdateStocksSymbolDataService) SpringUtils.getBean(UpdateStocksSymbolDataService.class);
        iDownTradedataFailService = (IDownTradedataFailService) SpringUtils.getBean(IDownTradedataFailService.class);
        step1();
        downLoadTradedataScheduleMapper.updateDownTradedataSchedule(new DownTradedataSchedule("download_schedule", "000000"));
        downLoadTradedataScheduleMapper.updateDownTradedataSchedule(new DownTradedataSchedule("delete_tradedata", "000000"));
    }

    public void step1() {
        //获取系统已经完成下载数据日期
        String lastDownLoadDateFromSina = downLoadTradedataScheduleMapper.selectDownTradedataScheduleByName("lastDownLoadFromSinaDate").getValue();
        String diyDownloadDate = downLoadTradedataScheduleMapper.selectDownTradedataScheduleByName("diyDownloadDate").getValue();
        if (StringUtils.isEmpty(diyDownloadDate) || "null".equals(diyDownloadDate)) {
            now163Date = CheckSourceReadyFromQQ1.checkSourceReady();
        } else {//如果不为空，表示允许交易数据下载到用户自己设定的日期，如下载数据已经隔夜了，需要暂时中断，回头再下载
            now163Date = diyDownloadDate;
        }
        log.warn("### now163Date:"+now163Date);
        //获取sinajs已经完成数据日期
        if (now163Date!=null && !"".equals(now163Date) && now163Date.compareTo(lastDownLoadDateFromSina) > 0) {

            //中断后重新开始下载的处理 begin
            DownTradedataSchedule ac = downLoadTradedataScheduleMapper.selectDownTradedataScheduleByName("download_schedule");
            if (!ac.getValue().equals("000000")) {
                downLoadTradedataScheduleMapper.updateDownTradedataSchedule(new DownTradedataSchedule("delete_tradedata", "开始删除" + ac.getValue() + " " + lastDownLoadDateFromSina + "日之后日期的数据"));
                TRADEDATA tradeDatakey = new TRADEDATA();
                tradeDatakey.setSymbol(ac.getValue());
                tradeDatakey.setDatetime(DateUtils2.formatStringToDate(lastDownLoadDateFromSina, "yyyy-MM-dd"));
                //删除股票代码大于等于symbol并且日期大于lastDownLoadDateFromSina 的数据
                tradedataMapper.deleteByPrimaryKey(tradeDatakey);
                downLoadTradedataScheduleMapper.updateDownTradedataSchedule(new DownTradedataSchedule("delete_tradedata", "完成删除" + ac.getValue() + " " + lastDownLoadDateFromSina + "日之后日期的数据"));
            }
            //中断后重新开始下载的处理 end
            downLoadTradeData(lastDownLoadDateFromSina, now163Date);

        } else {
            DownTradedataSchedule dts = new DownTradedataSchedule("sinadata_ready?", "交易历史数据未准备好");
            dts.setRemark("交易历史数据未准备好或者有自定义日期");
            downLoadTradedataScheduleMapper.updateDownTradedataSchedule(dts);
        }

    }


    public void downLoadTradeData(String lastDownLoadDateFromSina, String nowDate) {

        List<STOCK> stocks = stockMapper.selectSTOCKList(null);//from stock order by SYMBOL ASC
        DownTradedataSchedule ac = downLoadTradedataScheduleMapper.selectDownTradedataScheduleByName("download_schedule");
        for (int k = 0; k < stocks.size(); k++) {// list遍历 非已退市
            if (stocks.get(k).getSymbol().compareTo(ac.getValue()) < 0) {
                continue;
            }
            DownTradedataSchedule ac1 = downLoadTradedataScheduleMapper.selectDownTradedataScheduleByName("download_schedule");
            ac1.setValue(stocks.get(k).getSymbol());
            downLoadTradedataScheduleMapper.updateDownTradedataSchedule(ac1);

            whileflag11 = true;

            int i = 0 ;
            while (whileflag11 && i<2) {// 循环调用下载程序直到成功
                if(i>=1){
                    log.warn("再次抓取! symbol:"+stocks.get(k).getSymbol() + " 日期 " +  lastDownLoadDateFromSina.replace("-", "") + "--" + nowDate.replace("-", ""));
                }
                downloadData(stocks.get(k).getSymbol(), lastDownLoadDateFromSina.replace("-", ""), nowDate.replace("-", ""));
                //非全量下载时 使用的时间间隔
                try {
                    Thread.sleep(4000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                i++;

            }


        }
    }

/*

SimpleDateFormat sFormat = new SimpleDateFormat("yyyy-MM-dd");
		Date date = new Date();
		String year = String.valueOf((Integer.valueOf(sFormat.format(date).split("-")[0])-2000));
		//String url2 = "http://data.gtimg.cn/flashdata/hushen/daily/"+year+"/sz399001.js";
		String url2 = "http://data.gtimg.cn/flashdata/hushen/daily/"+year+"/sz399001.js";

		//http://data.gtimg.cn/flashdata/hushen/daily/20/sh000001.js
		//http://data.gtimg.cn/flashdata/hushen/daily/20/sz399001.js
		//http://data.gtimg.cn/flashdata/hushen/daily/20/sz399102.js
 */
    private void downloadData(String symbol, String lastDownLoadDateFromSina, String nowDate) {

        String code = "sz" + symbol;
        if ("999001".equals(symbol)) {
            code = "sz399001";
        }
        if ("900001".equals(symbol)) {
            code = "sh000001";
        }
        if ("999006".equals(symbol)) {
            code = "sz399102";
        }
        if (symbol.startsWith("6")) {
            code = "sh" + symbol;
        }
        BufferedReader bufferedReader = null;
        List<TRADEDATA> temp1 = new ArrayList<TRADEDATA>(30);
        int csize = 100;
        if(lastDownLoadDateFromSina.startsWith("2004")){
            csize = 4000;
        }
        List<TRADEDATA> concurrentLinkedQueue = new ArrayList<TRADEDATA>(csize);

        SimpleDateFormat sFormat = new SimpleDateFormat("yyyyMMdd");
        Date date = new Date();
        String year = String.valueOf((Integer.valueOf(sFormat.format(date).substring(0,4))-2000));
        if(lastDownLoadDateFromSina.substring(4).compareTo("1231")<=0){
            year = lastDownLoadDateFromSina.substring(2,4);
        }

        String url2 = "http://data.gtimg.cn/flashdata/hushen/daily/"+year+"/"+code+".js";

        try {
            Response resultImageResponse = Jsoup.connect(url2)
                    .ignoreContentType(true)
                    .execute();

            bufferedReader = new BufferedReader(new InputStreamReader(resultImageResponse.bodyStream(), "GBK"));
            String s = bufferedReader.readLine();

            while ((s = bufferedReader.readLine()) != null) {
                String [] lines = s.split("\\s");
                if(lines.length==6){
                    String tradeDate = "20"+lines[0];
                    if(tradeDate.compareTo(lastDownLoadDateFromSina)>0 && tradeDate.compareTo(nowDate)<=0){
                        String open = lines[1];
                        String close= lines[2];
                        String high = lines[3];
                        String low = lines[4];
                        String volume = lines[5].split("\\\\")[0];
                        BigDecimal amount = new BigDecimal(volume).multiply(new BigDecimal(close)).multiply(new BigDecimal(0.01)).setScale(2, BigDecimal.ROUND_HALF_UP);

                        TRADEDATA tradeData = new TRADEDATA();
                        tradeData.setDatetime(DateUtils2.formatStringToDate(tradeDate, "yyyyMMdd"));
                        tradeData.setSymbol(symbol);
                        tradeData.setCloseprice(new BigDecimal(close));
                        tradeData.setHighprice(new BigDecimal(high));
                        tradeData.setLowprice(new BigDecimal(low));
                        tradeData.setDateopenprice(new BigDecimal(open));
                        tradeData.setVolume(new BigDecimal(volume));
                        tradeData.setAmount(amount);

                        if(lastDownLoadDateFromSina.startsWith("2004")){
                            concurrentLinkedQueue.add(tradeData);
                        }else{
                            TRADEDATA key = new TRADEDATA(symbol, tradeData.getDatetime());
                            List<TRADEDATA> tradeData1 = tradedataMapper.selectTRADEDATAList(key);
                            if (tradeData1.size() == 0) {
                                concurrentLinkedQueue.add(tradeData);
                            }
                        }
                    }
                }
            }

            if (concurrentLinkedQueue.size() > 0) {
                int sizec = concurrentLinkedQueue.size()-1;

                for (int i = sizec; i >= 0; i--) {
                    temp1.add(concurrentLinkedQueue.get(i));
                    if (temp1.size() == 30) {
                        tradedataMapper.insertTRADEDATA2(temp1);
                        temp1.clear();
                    }
                }

                if (temp1.size() > 0) {
                    tradedataMapper.insertTRADEDATA2(temp1);
                    temp1.clear();
                }
            }

            whileflag11 = false;
            concurrentLinkedQueue = null;
        } catch (java.net.SocketTimeoutException e1) {
            e1.printStackTrace();
            log.warn("下载数据报错downloadData5_31() SocketTimeoutException:symbol:"+symbol + ", lastDownLoadDateFromSina:" + lastDownLoadDateFromSina + ", nowDate:"+  nowDate);
        } catch (UnknownHostException e1) {
            e1.printStackTrace();
            insertFailSymbol(symbol, lastDownLoadDateFromSina, nowDate);
            log.warn("下载数据报错downloadData5_31() UnknownHostException:symbol: "+symbol + ", lastDownLoadDateFromSina:" + lastDownLoadDateFromSina + ", nowDate:"+  nowDate);
        } catch (org.jsoup.HttpStatusException e1) {
            if(e1.getStatusCode() == 404){
                log.warn("404异常 股票停牌");
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (bufferedReader != null) {
                    bufferedReader.close();
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }



    public void insertFailSymbol(String symbol, String from, String to){
        DownTradedataFail dtf = iDownTradedataFailService.selectDownTradedataFailById(symbol);
        if(dtf==null){
            dtf = new DownTradedataFail();
            dtf.setSymbol(symbol);
            dtf.setFromdate(from);
            dtf.setTodate(to);
            iDownTradedataFailService.insertDownTradedataFail(dtf);
        }
    }

    public static void main(String[] args) {
        String lastDownLoadDateFromSina = "20201230";
        String year = null;
        if(lastDownLoadDateFromSina.substring(4).compareTo("1231")<=0){
            year = lastDownLoadDateFromSina.substring(2,4);
        }
        System.out.println(lastDownLoadDateFromSina.substring(4));
        System.out.println(year);
    }
}
